package com.example.lockandqueue;

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

public class AQSMain {

    public static void main(String[] args) {
        AQSMain.MyAQS myAQS = new AQSMain.MyAQS();
        boolean b = myAQS.tryAcquire(1);
        System.out.println(b);
        new Thread(()->{
            boolean b1 = myAQS.tryAcquire(1);
            System.out.println(b1);
        }).start();
        boolean b1 = myAQS.tryAcquire(1);
        System.out.println(b1);
        int states = myAQS.getStates();
        System.out.println(states);
        boolean b2 = myAQS.tryRelease(1);
        System.out.println(b2);
        myAQS.acquire(2);
        myAQS.acquire(2);
    }
    
    public static class MyAQS extends AbstractQueuedSynchronizer {

        @Override
        protected boolean tryAcquire(int arg) {
            if(compareAndSetState(0,1)){
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        @Override
        protected boolean tryRelease(int arg) {
            if(getState()==0){
                return false;
            }
            setState(0);
            setExclusiveOwnerThread(null);
            return true;
        }

        @Override
        protected int tryAcquireShared(int arg) {
            return super.tryAcquireShared(arg);
        }

        @Override
        protected boolean tryReleaseShared(int arg) {
            return super.tryReleaseShared(arg);
        }

        @Override
        protected boolean isHeldExclusively() {
            return super.isHeldExclusively();
        }

        public int getStates(){
            return super.getState();
        }
    }
    
}
